<?php

namespace app\api\model\house;


use addons\epay\library\Service;
use app\admin\model\Crontab;
use app\api\model\coupon\Coupon;
use app\common\model\User;
use think\Db;
use think\Log;
use think\Model;
use Yansongda\Pay\Pay;


class HouseOrder extends Model
{





    // 表名
    protected $name = 'house_order';

    // 自动写入时间戳字段
    protected $autoWriteTimestamp = 'integer';

    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';
    protected $deleteTime = false;

    // 追加属性
    protected $append = [
        'checkin_date_week_text',
        'leave_date_week_text',
    ];

    protected $weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];

    public function getCheckinDateWeekTextAttr($value, $data)
    {
        $timestamp = strtotime($data['checkin_date']);
        $weekday = date('w', $timestamp);
        return $this->weekdays[$weekday];
    }


    public function getLeaveDateWeekTextAttr($value, $data)
    {
        $timestamp = strtotime($data['leave_date']);
        $weekday = date('w', $timestamp);
        return $this->weekdays[$weekday];
    }

    public $order_type = 1;

    // 订单创建
    const ORDER_CREATE = 0;

    // 订单待入住
    const ORDER_WAIT_CHECKIN = 1;

    //已入住
    const ORDER_CHECKIN = 2;

    //已退房
    const ORDER_CHECKIN_OUT = 4;

    //已完成
    const ORDER_COMPLETE = 10;

    //已取消
    const ORDER_CLOSE = -1;

    public $order_status = [
        self::ORDER_CREATE           => [
            'status'          => self::ORDER_CREATE,
            'name'            => '待支付',
        ],
        self::ORDER_WAIT_CHECKIN           => [
            'status'          => self::ORDER_WAIT_CHECKIN,
            'name'            => '待入住',
        ],
        self::ORDER_CHECKIN           => [
            'status'          => self::ORDER_CHECKIN,
            'name'            => '已入住',
        ],
        self::ORDER_CHECKIN_OUT           => [
            'status'          => self::ORDER_CHECKIN_OUT,
            'name'            => '已退房',
        ],
        self::ORDER_COMPLETE           => [
            'status'          => self::ORDER_COMPLETE,
            'name'            => '已完成',
        ],
        self::ORDER_CLOSE           => [
            'status'          => self::ORDER_CLOSE,
            'name'            => '已取消',
        ],
    ];

    //支付回调
    public function notify($order_no,$paytype)
    {
        $order = HouseOrder::get(['order_no' => $order_no]);
        if ($order->pay_status==0){
            $update_data = [
                'pay_type'=>$paytype,
                'order_status'=>self::ORDER_WAIT_CHECKIN,
                'order_status_name'=>$this->order_status[self::ORDER_WAIT_CHECKIN]['name'],
                'owner_order_status'=>self::ORDER_WAIT_CHECKIN,
                'owner_order_status_name'=>$this->order_status[self::ORDER_WAIT_CHECKIN]['name'],
                'pay_status'=>1,
                'pay_time'=>time()
            ];
            $res = HouseOrder::where(['order_no' => $order_no])->update($update_data);

            HouseOrderActionLog::add($order->order_id,$order->user_id,'user','用户支付');

            \app\api\model\User::where(['id'=>$order->user_id])->setInc('order_money',$order->pay_money);
            User::where(['id'=>$order->user_id])->setInc('order_num',1);
            User::upgradelevel($order->user_id);
            return $res;
        }
        return true;
    }

    //业主订单列表
    public function getManageOrderPageList($data)
    {
        $order_status = $data['order_status'];
        $order_type = $data['order_type'];

        $where = ['ho.owner_id'=>$data['owner_id'],'ho.order_type'=>$order_type];

        switch ( $order_status ) {
            case "waitcheckin"://待入住
                $where['ho.owner_order_status'] = 1;
                break;
            case "checkin"://已入住
                $where['ho.owner_order_status'] = 2;
                break;
            case "retreat"://已退房
                $where['ho.owner_order_status'] = 4;
                break;
            case "complete"://已完成
                $where['ho.owner_order_status'] = 10;
                break;
            case "cancel"://已取消
                $where['ho.owner_order_status'] = -1;
                break;
        }

        $list = HouseOrder::alias('ho')
            ->join('house h','ho.house_id = h.house_id')
            ->where($where)
            ->field('ho.*')
            ->order('ho.createtime desc')
            ->paginate(10, false, ['query' => request()->get()]);

        $auto_close = \app\common\model\Config::get(['name'=>'house_close_time'])->value*60;

        foreach ($list as $k=>$v){
            $list[$k]['auto_close'] = $v['createtime'] + $auto_close-time();
            if ($v['order_type']==1){
                $bed_list = HouseBedInfo::where('bed_id','in',$v['bed_id'])->column('bed_name');
                $list[$k]['bed_name'] = implode(',',$bed_list);
            }
        }

        return $list;
    }

    //拼房订单详情
    public function getGroupOrderInfo($order_id)
    {
        $info = HouseOrder::where(['order_id'=>$order_id])->find();
        if (!$info)throw new \Exception('订单不存在');

        //房屋信息
        $house_info = House::alias('h')
            ->join('house_park hp','hp.house_id = h.house_id')
            ->where(['h.house_id'=>$info['house_id']])
            ->field('h.house_id,h.house_title,h.address,h.lat,h.lng,h.province,h.city,h.house_number,h.area,h.community,
            h.bedroom_num,h.livingroom_num,h.kitchen_num,h.bathroom_num,h.house_type_id,h.mode,h.is_group,hp.name')
            ->find();

        $house_type_model = new HouseType();
        $type_list = $house_type_model->getTypeList();
        $house_type_list = [];
        foreach ($type_list as $k=>$v){
            $list = HouseType::where(['type'=>$k])->where('type_id','in',$house_info['house_type_id'])
                ->order('weigh desc')->field('type_id,name')->select();

            if (count($list)>0){
                $house_type_list[] = [
                    'title'=>$v,
                    'data'=>$list
                ];
            }
        }
        $house_info['house_type_list'] = $house_type_list;
        $info['house_info'] = $house_info;

        $bed_list = HouseBedInfo::where('bed_id','in',$info['bed_id'])->column('bed_name');

        $info['bed_name'] = implode(',',$bed_list);

        //dump($house_info);die;
        //日期价格
        $info['date_list'] = HouseOrderDate::alias('od')
            ->join('house_bed_info h','od.bed_id = h.bed_id')
            ->where(['od.order_id'=>$order_id])
            ->field('od.date_id,od.bed_id,od.order_id,od.date,od.price,h.bed_name')
            ->select();

        //入住人
        $info['occupant_list'] = HouseOrderOccupant::alias('od')
            ->join('house_bed_info h','od.bed_id = h.bed_id')
            ->where(['od.order_id'=>$order_id])
            ->field('od.user_id,od.bed_id,od.order_id,od.name,od.mobile,od.id_card_num,h.bed_name')
            ->select();

        //服务
        $info['complement_list'] = HouseOrderComplement::where(['order_id'=>$order_id])
            ->field('num,order_id,single_money,total_money,name,unit')->select();

        return $info;
    }

    //用户拼房订单详情
    public function getUserGroupOrderInfo($order_id,$user_id)
    {
        $info = HouseOrder::where(['order_id'=>$order_id,'user_id'=>$user_id])->find();
        if (!$info)throw new \Exception('不是当前用户订单');

        //房屋信息
        $house_info = House::alias('h')
            ->join('house_park hp','hp.house_id = h.house_id')
            ->where(['h.house_id'=>$info['house_id']])
            ->field('h.house_id,h.house_title,h.address,h.lat,h.lng,h.province,h.city,h.house_number,h.area,h.community,
            h.bedroom_num,h.livingroom_num,h.kitchen_num,h.bathroom_num,h.house_type_id,h.mode,h.is_group,hp.name')
            ->find();

        $house_type_model = new HouseType();
        $type_list = $house_type_model->getTypeList();
        $house_type_list = [];
        foreach ($type_list as $k=>$v){
            $list = HouseType::where(['type'=>$k])->where('type_id','in',$house_info['house_type_id'])
                ->order('weigh desc')->field('type_id,name')->select();

            if (count($list)>0){
                $house_type_list[] = [
                    'title'=>$v,
                    'data'=>$list
                ];
            }
        }
        $house_info['house_type_list'] = $house_type_list;
        $info['house_info'] = $house_info;

        $bed_list = HouseBedInfo::where('bed_id','in',$info['bed_id'])->column('bed_name');

        $info['bed_name'] = implode(',',$bed_list);

        //dump($house_info);die;
        //日期价格
        $info['date_list'] = HouseOrderDate::alias('od')
            ->join('house_bed_info h','od.bed_id = h.bed_id')
            ->where(['od.order_id'=>$order_id])
            ->field('od.date_id,od.bed_id,od.order_id,od.date,od.price,h.bed_name')
            ->select();

        //入住人
        $info['occupant_list'] = HouseOrderOccupant::alias('od')
            ->join('house_bed_info h','od.bed_id = h.bed_id')
            ->where(['od.order_id'=>$order_id])
            ->field('od.user_id,od.bed_id,od.order_id,od.name,od.mobile,od.id_card_num,h.bed_name')
            ->select();

        //服务
        $info['complement_list'] = HouseOrderComplement::where(['order_id'=>$order_id])
            ->field('num,order_id,single_money,total_money,name,unit')->select();

        return $info;
    }

    //用户订单列表
    public function getUserOrderPageList($data)
    {
        $order_status = $data['order_status'];
        $order_type = $data['order_type'];

        $where = ['ho.user_id'=>$data['user_id'],'ho.order_type'=>$order_type];

        switch ( $order_status ) {
            case "waitpay"://待支付
                $where['ho.order_status'] = 0;
                break;
            case "waitcheckin"://待入住
                $where['ho.order_status'] = 1;
                break;
            case "checkin"://已入住
                $where['ho.order_status'] = 2;
                break;
            case "retreat"://已退房
                $where['ho.order_status'] = 4;
                break;
            case "complete"://已完成
                $where['ho.order_status'] = 10;
                break;
            case "cancel"://已取消
                $where['ho.order_status'] = -1;
                break;
        }

        $list = HouseOrder::alias('ho')
            ->join('house h','ho.house_id = h.house_id')
            ->where($where)
            ->field('ho.*')
            ->order('ho.createtime desc')
            ->paginate(10, false, ['query' => request()->get()]);

        $auto_close = \app\common\model\Config::get(['name'=>'house_close_time'])->value*60;

        foreach ($list as $k=>$v){
            $list[$k]['auto_close'] = $v['createtime'] + $auto_close-time();
            if ($v['order_type']==1){
                $bed_list = HouseBedInfo::where('bed_id','in',$v['bed_id'])->column('bed_name');
                $list[$k]['bed_name'] = implode(',',$bed_list);
            }
        }

        return $list;
    }

    //整房订单详情
    public function getOrderInfo($order_id)
    {
        $info = HouseOrder::where(['order_id'=>$order_id])->find();
        if (!$info)throw new \Exception('订单不存在');

        //房屋信息
        $house_info = House::alias('h')
            ->join('house_park hp','hp.house_id = h.house_id')
            ->where(['h.house_id'=>$info['house_id']])
            ->field('h.house_id,h.house_title,h.address,h.lat,h.lng,h.province,h.city,h.house_number,h.area,h.community,
            h.bedroom_num,h.livingroom_num,h.kitchen_num,h.bathroom_num,h.house_type_id,h.mode,h.is_group,h.score,h.describe_score,
            h.location_score,h.convenient_score,h.service_score,h.health_score,h.cost_performance_score,hp.name')
            ->find();

        $house_type_model = new HouseType();
        $type_list = $house_type_model->getTypeList();
        $house_type_list = [];
        foreach ($type_list as $k=>$v){
            $list = HouseType::where(['type'=>$k])->where('type_id','in',$house_info['house_type_id'])
                ->order('weigh desc')->field('type_id,name')->select();

            if (count($list)>0){
                $house_type_list[] = [
                    'title'=>$v,
                    'data'=>$list
                ];
            }
        }
        $house_info['house_type_list'] = $house_type_list;
        $info['house_info'] = $house_info;
        //dump($house_info);die;
        //日期价格
        $info['date_list'] = HouseOrderDate::where(['order_id'=>$order_id])
            ->field('date_id,order_id,date,price')->select();

        //入住人
        $info['occupant_list'] = HouseOrderOccupant::where(['order_id'=>$order_id])
            ->field('user_id,order_id,name,mobile,id_card_num')->select();

        //服务
        $info['complement_list'] = HouseOrderComplement::where(['order_id'=>$order_id])
            ->field('num,order_id,single_money,total_money,name,unit')->select();

        //操作记录
        $log_list = HouseOrderActionLog::alias('l')
            ->join('user u','l.user_id = u.id')
            ->where(['l.order_id'=>$order_id])
            ->field('l.*,u.nickname,u.avatar')
            ->select();
        $info['action_log_list'] = $log_list;

        //评价
        $evaluate_info = HouseEvaluate::where(['house_id'=>$info['house_id'],'order_id'=>$order_id])
            ->find();
        $info['evaluate_info'] = $evaluate_info;
        return $info;
    }

    //用户整房订单详情
    public function getUserOrderInfo($order_id,$user_id)
    {
        $info = HouseOrder::where(['order_id'=>$order_id,'user_id'=>$user_id])->find();
        if (!$info)throw new \Exception('不是当前用户订单');

        //房屋信息
        $house_info = House::alias('h')
            ->join('house_park hp','hp.house_id = h.house_id')
            ->where(['h.house_id'=>$info['house_id']])
            ->field('h.house_id,h.house_title,h.address,h.lat,h.lng,h.province,h.city,h.house_number,h.area,h.community,
            h.bedroom_num,h.livingroom_num,h.kitchen_num,h.bathroom_num,h.house_type_id,h.mode,h.is_group,hp.name')
            ->find();

        $house_type_model = new HouseType();
        $type_list = $house_type_model->getTypeList();
        $house_type_list = [];
        foreach ($type_list as $k=>$v){
            $list = HouseType::where(['type'=>$k])->where('type_id','in',$house_info['house_type_id'])
                ->order('weigh desc')->field('type_id,name')->select();

            if (count($list)>0){
                $house_type_list[] = [
                    'title'=>$v,
                    'data'=>$list
                ];
            }
        }
        $house_info['house_type_list'] = $house_type_list;
        $info['house_info'] = $house_info;
        //dump($house_info);die;
        //日期价格
        $info['date_list'] = HouseOrderDate::where(['order_id'=>$order_id])
            ->field('date_id,order_id,date,price')->select();

        //入住人
        $info['occupant_list'] = HouseOrderOccupant::where(['order_id'=>$order_id])
            ->field('user_id,order_id,name,mobile,id_card_num')->select();

        //服务
        $info['complement_list'] = HouseOrderComplement::where(['order_id'=>$order_id])
            ->field('num,order_id,single_money,total_money,name,unit')->select();

        return $info;
    }

    //取消订单
    public function orderCancel($order_id)
    {

        $info = HouseOrder::where(['order_id'=>$order_id])->find();

        if ($info['order_status']==-1)return true;

        $data = [
            'order_status'=>self::ORDER_CLOSE,
            'order_status_name'=>$this->order_status[self::ORDER_CLOSE]["name"],
            'owner_order_status'=>self::ORDER_CLOSE,
            'owner_order_status_name'=>$this->order_status[self::ORDER_CLOSE]["name"],
            'cancel_time'=>time()
        ];

        if ($info['coupon_id']){
            $coupon_model = new Coupon();
            $coupon_model->refundCoupon($info['coupon_id'],$info['user_id']);
        }

        //换房扣的积分退回
        if ($info['use_score']<0&&$info['order_type']==3){
            User::score(abs($info['use_score']),$info['user_id'],$info['change_type_name'].'换房订单关闭退回',$order_id);
        }

        //付款的退款
        //在入住日前3天免费取消订单。取消订单后，预订支付的款项全部原路返回用户支付账号。
        //因离入住日1天至3天时间内取消订单，预订支付的款项扣取50%.
        //入住当日取消订单，预订支付的款项不能退回
        if ($info['pay_status']==1&&$info['pay_money']>0){
            $rate = 1;
            $checkin_date_timestamp = strtotime($info['checkin_date']);
            $time = time();
            $date = date('Y-m-d');
            if ($checkin_date_timestamp-$time>3){
                $rate = 1;
            } elseif ($info['checkin_date']==$date){
                $rate = 0;
            } elseif ($checkin_date_timestamp-$time>=1&&$checkin_date_timestamp-$time<=3){
                $rate = 0.5;
            }

            $refund_price = bcmul($info['pay_money'],$rate,2);
            $refund_service_money = bcsub($info['pay_money'],$refund_price,2);
            if ($refund_price>0){
                $refund_res = $this->refundoperate($info->order_no, 'wechat',$refund_price);
                if (!$refund_res){
                    Db::rollback();
                    throw new \Exception('退款失败');
                }
                $data['refund_status'] = 1;
                $data['refund_money'] = $refund_price;
                $data['refund_service_money'] = $refund_service_money;
            }

        }

        $res = HouseOrder::where(['order_id'=>$order_id])->update($data);

        return $res;
    }

    //用户确认入驻
    public function orderUserCheckin($order_id)
    {
        $info = HouseOrder::where(['order_id'=>$order_id])->find();

        if ($info['order_status']==2)return true;
        $data = [
            'order_status'=>self::ORDER_CHECKIN,
            'order_status_name'=>$this->order_status[self::ORDER_CHECKIN]["name"],
            'user_checkin_time'=>time()
        ];

        $res = HouseOrder::where(['order_id'=>$order_id])->update($data);
        HouseOrderActionLog::add($order_id,$info['user_id'],'user','确认入住');

        //定时任务到离开日期*小时自动确认退房
        $cron = new Crontab();
        $auto_checkout_time = \app\common\model\Config::get(['name'=>'user_order_auto_checkout_time'])->value;
        $end_time_timestamp = time()+3600*$auto_checkout_time;
        $cron_data = [
            'type'=>'url',
            'title'=>'自动确认退房,订单id:'.$order_id,
            'content'=>request()->domain().'/api/houseorder/checkout?order_id='.$order_id,
            'schedule'=>schedule($end_time_timestamp),
            'maximums'=>1,
            'begintime'=>time(),
            'endtime'=>$end_time_timestamp,
            'status'=>'normal'
        ];
        $cron->save($cron_data);
        return $res;
    }

    //业主确认入驻
    public function orderManageCheckin($order_id)
    {
        $info = HouseOrder::where(['order_id'=>$order_id])->find();

        if ($info['owner_order_status']==2)return true;
        $data = [
            'owner_order_status'=>self::ORDER_CHECKIN,
            'owner_order_status_name'=>$this->order_status[self::ORDER_CHECKIN]["name"],
            'owner_checkin_time'=>time()
        ];

        $res = HouseOrder::where(['order_id'=>$order_id])->update($data);
        HouseOrderActionLog::add($order_id,$info['owner_id'],'owner','确认入住');
        return $res;
    }

    //用户确认退房
    public function orderUserCheckout($order_id)
    {
        $info = HouseOrder::where(['order_id'=>$order_id])->find();

        if ($info['order_status']==4)return true;
        $data = [
            'order_status'=>self::ORDER_CHECKIN_OUT,
            'order_status_name'=>$this->order_status[self::ORDER_CHECKIN_OUT]["name"],
            'user_checkout_time'=>time()
        ];

        $res = HouseOrder::where(['order_id'=>$order_id])->update($data);
        HouseOrderActionLog::add($order_id,$info['user_id'],'user','确认退房');

        //定时任务到离开日期*小时自动确认退房
        //退房后24小时无投诉/无争议后，订单才是已完成状态。
        $cron = new Crontab();
        $auto_checkout_time = \app\common\model\Config::get(['name'=>'order_auto_complete_time'])->value;
        $end_time_timestamp = time()+3600*$auto_checkout_time;
        $cron_data = [
            'type'=>'url',
            'title'=>'自动完成,订单id:'.$order_id,
            'content'=>request()->domain().'/api/houseorder/autocomplete?order_id='.$order_id,
            'schedule'=>schedule($end_time_timestamp),
            'maximums'=>1,
            'begintime'=>time(),
            'endtime'=>$end_time_timestamp,
            'status'=>'normal'
        ];
        $cron->save($cron_data);
        return $res;
    }

    //业主确认退房
    public function orderOwnerCheckout($order_id)
    {
        $info = HouseOrder::where(['order_id'=>$order_id])->find();

        if ($info['owner_order_status']==4)return true;
        $data = [
            'owner_order_status'=>self::ORDER_CHECKIN_OUT,
            'owner_order_status_name'=>$this->order_status[self::ORDER_CHECKIN_OUT]["name"],
            'owner_checkout_time'=>time()
        ];

        $res = HouseOrder::where(['order_id'=>$order_id])->update($data);
        HouseOrderActionLog::add($order_id,$info['owner_id'],'owner','确认退房');
        return $res;
    }


    /**
     * 退款操作
     */
    public function refundoperate($order_sn, $paytype, $payamount)
    {
        $config = Service::getConfig($paytype);
        try {
            //$order = Order::getByOrderSn($order_sn);

            $response = Pay::wechat($config)->refund([
                'type'          => 'app',
                'out_trade_no'  => $order_sn,
                'out_refund_no' => time(),
                'total_fee'     => $payamount * 100,
                'refund_fee'    => $payamount * 100
            ]);

            if (!$response['result_code'] || $response['result_code'] != 'SUCCESS') {
                throw new \Exception(($response['err_code'] ?? '') . ':' . ($response['err_code_des'] ?? '未知退款错误'));
            }

        } catch (\Exception $e) {
            Log::write("[{$order_sn}]同步退款失败，失败原因：" . $e->getMessage(), 'refund');
            throw new \Exception("同步退款失败，失败原因：" . $e->getMessage());

        }

        return true;
    }


    //用户确认订单完成
    public function orderUserConfirm($order_id)
    {
        $info = HouseOrder::where(['order_id'=>$order_id])->find();

        $count = HouseOrderComplain::where(['order_id'=>$order_id,'status'=>0])->count();//投诉数量

        if ($count>0){
            throw new \Exception("存在投诉");
        }

        if ($info['order_status']==10)return true;
        $data = [
            'order_status'=>self::ORDER_COMPLETE,
            'order_status_name'=>$this->order_status[self::ORDER_COMPLETE]["name"],
            'user_complete_time'=>time()
        ];

        $res = HouseOrder::where(['order_id'=>$order_id])->update($data);

        HouseOrderActionLog::add($order_id,$info['user_id'],'user','确认订单完成');
        return $res;
    }

    //用户确认订单完成
    public function orderOwnerConfirm($order_id)
    {
        $info = HouseOrder::where(['order_id'=>$order_id])->find();

        $count = HouseOrderComplain::where(['order_id'=>$order_id,'status'=>0])->count();//投诉数量

        if ($count>0){
            throw new \Exception("存在投诉");
        }

        if ($info['order_status']==10)return true;

        $data = [
            'owner_order_status'=>self::ORDER_COMPLETE,
            'owner_order_status_name'=>$this->order_status[self::ORDER_COMPLETE]["name"],
            'owner_complete_time'=>time()
        ];

        User::score($info['earn_score'],$info['user_id'],$info['change_type_name'].'得到积分',$order_id);

        $res = HouseOrder::where(['order_id'=>$order_id])->update($data);

        HouseOrderActionLog::add($order_id,$info['owner_id'],'owner','确认订单完成');
        return $res;
    }


    //订单到期自动完成
    public function autocomplete($order_id)
    {
        //退房后24小时无投诉/无争议后，订单才是已完成状态。
        $info = HouseOrder::where(['order_id'=>$order_id])->find();

        $count = HouseOrderComplain::where(['order_id'=>$order_id,'status'=>0])->count();//投诉数量

        if ($count>0){
            throw new \Exception("存在投诉");
        }

        //if ($info['order_status']==10)return true;
        $data = [
            'owner_order_status'=>self::ORDER_COMPLETE,
            'owner_order_status_name'=>$this->order_status[self::ORDER_COMPLETE]["name"],
            'owner_complete_time'=>time(),
            'order_status'=>self::ORDER_COMPLETE,
            'order_status_name'=>$this->order_status[self::ORDER_COMPLETE]["name"],
            'user_complete_time'=>time()
        ];

        $res = HouseOrder::where(['order_id'=>$order_id])->update($data);

        User::score($info['earn_score'],$info['user_id'],$info['change_type_name'].'得到积分',$order_id);

        HouseOrderActionLog::add($order_id,$info['user_id'],'user','到期自动完成');
        HouseOrderActionLog::add($order_id,$info['owner_id'],'owner','到期自动完成');
        return $res;
    }
}
